package dS.ProjectGPS.GPS;

import dS.ProjectGPS.*;
import dS.ProjectGPS.Bluetooth.*;

import java.io.*;
import javax.microedition.lcdui.*;
import java.util.Vector;

/**
 * <p>Title: NMEA Reader</p>
 *
 * <p>Description: Creates new thread to loop through and decode a continuous
 *                 NMEA sentence stream. Thread sleeps after a predefined
 *                 amount of NMEA sentences to prevent overloading of phone.
 *                 ie. This tread creates multiple NMEA class instances/threads/
 * </p>
 *
 * <p>Copyright: Copyright (c) 2005</p>
 *
 * @author David So
 * @version 1.0
 */

public class NMEAReader extends Thread {

  Display display;
  Navigator navigator;

  boolean running = false;
  private static final int SLEEP_ON_LOOP = 7;
  private static final int SLEEP_TIME = 2000; // in ms
  private static final int LOG_AFTER_LOOP = 998;

  public boolean rawSet = false;
  public InputStream rawIn = null;

  // Displays the incoming data on screen
  public static MessageUI debug = new MessageUI();

  public static Vector logPosition = new Vector(); // Type: Position

  public NMEAReader(Navigator n, Display d) {
    navigator = n;
    display = d;

    debug.setCommandListener(n);
  }

  public void run() {
    System.out.println("Navigator Started");
    debug.add("Navigator Started");

    // Remove commenting of below in final version
    if(rawIn == null){
      Alert alert = new Alert("Navigator", "Bluetooth device not connected", null,
                        AlertType.INFO);
      alert.setTimeout(3000);
      display.setCurrent(alert, ProjectGPSme.mainMenu);

    } else {
      navigator.removeCommand(navigator.CMD_NMEA_START);
      navigator.addCommand(navigator.CMD_NMEA_STOP);
      navigator.addCommand(navigator.CMD_SMS);
      running = true;
    }



    String nmeaSentence = new String();
    int loopCounter = 0;

    while(running){

      loopCounter = (loopCounter + 1) % 1000;

      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      int ch = 0;

      try {
        while ((ch = rawIn.read()) != '\n') {
          baos.write(ch);
        }
        baos.flush();
      }
      catch (Exception e) {
        debug.add("Couldn't write/flush ByteArrayOutputStream" + e);
      }
      nmeaSentence = baos.toString();
   //   debug.addNoRepaint("nmeaSentence = " + nmeaSentence);

      try {
        baos.close();
      }
      catch (IOException ex) {
        debug.add("Couldn't close ByteArrayOutputStream" + ex);
      }

      // Create new NMEA thread - remove checksum data in the process
      // .substring(0, nmeaSentence.length() - 4) -- Causes NULL + String Exceptions atm
      NMEA nmea = new NMEA(nmeaSentence);

      if(loopCounter % LOG_AFTER_LOOP == 0 && NMEA.lat != "" && NMEA.lon != ""){
        logCurrentPoint();
      }

      if(loopCounter % SLEEP_ON_LOOP == 0){

        try {

          sleep(SLEEP_TIME);

      /*    debug.addNoRepaint("UTC: " + NMEA.UTC);
          debug.addNoRepaint("Lat: " + NMEA.NS + NMEA.lat);
          debug.addNoRepaint("Lon: " + NMEA.EW + NMEA.lon);
          debug.addNoRepaint("Speed: " + NMEA.speed);
          debug.addNoRepaint("Date: " + NMEA.date);
          debug.addNoRepaint("Alt: " + NMEA.alt);
          debug.addNoRepaint("HDOP: " + NMEA.HDOP); */

          //debug.add("NMEA: Sleep for 1 Seconds");
        } catch (Exception e){
          debug.add("Cant sleep NMEA thread");
        }
      }
    }
  }

  public void stop() {
    running = false;
    try {
      if (rawIn != null) {
        rawIn.close();
        rawSet = false;
      }
    }
    catch (Exception e) {
      // Ignore
    }
  }

  public static void logCurrentPoint(){
    logPosition.addElement(new Position(NMEA.lat, NMEA.lon));
  }
}
